﻿/**
* @title: JQuery Custom Tooltip
* @author: Michael Aguiar <michaelaguiar@me.com>
* @description: Allows you to replace the default tooltip with the style of your choice.
*/

(function($)
{
	$.fn.tooltip = function(settings)
	{
		settings = $.extend({
			id: 'tooltip',
			title: null,
			attrFlag: null,
			className: '',
			fade: true,
			elementDelay: 100,
			left: 15,
			top: 15,
			track: true,
			isStatic: false,
			callback: function() { }
		}, settings || {});

		var tooltipTimeout = null;
		var id = '#' + settings.id;
		var interact = false;

		function GetContent(element)
		{
			var text = null;
			settings.attrFlag = null;

			if ($(element).attr('alt') && $(element).attr('alt') !== null)
			{
				text = $(element).attr('alt');
				settings.title = $(element).attr('alt');
				$(element).attr('alt', '');
				settings.attrFlag = 0;
			}
			else if ($(element).attr('title') && $(element).attr('title') !== null)
			{
				text = $(element).attr('title');
				settings.title = $(element).attr('title');
				$(element).attr('title', '');
				settings.attrFlag = 1;
			}

			return text;
		}

		function GetPosition(e, id, element)
		{
			var width = $(id).width();
			var height = $(id).height();
			var offset = $(element).offset();

			if (settings.isStatic)
			{
				if (document.body.clientWidth < (e.pageX + width + settings.left + 15))
				{
					$(id).css({ 'left': offset.left - width + 20 + 'px' });
				}
				else
				{
					$(id).css({ 'left': offset.left + 'px' });
				}

				if (document.body.clientHeight < (e.pageY + height + settings.top + 15))
				{
					$(id).css({ 'top': offset.top - height - settings.top - 5 + 'px' });
				}
				else
				{
					$(id).css({ 'top': offset.top - height - settings.top - 15 + 'px' });
				}
			}
			else
			{
				if (document.body.clientWidth < (e.pageX + width + settings.left + 15))
				{
					$(id).css({ 'left': e.pageX - width - settings.left + 'px' });
				}
				else
				{
					$(id).css({ 'left': e.pageX + settings.left - 5 + 'px' });
				}

				if (document.body.clientHeight < (e.pageY + height + settings.top + 15))
				{
					$(id).css({ 'top': e.pageY - height - settings.top - 10 + 'px' });
				}
				else
				{
					$(id).css({ 'top': e.pageY + settings.top + 'px' });
				}
			}
		}

		$.each(this, function()
		{
			var html = $('<div id=' + settings.id + ' class=' + settings.className + '></div>');

			$(this).unbind('mouseover').unbind('mousemove').unbind('mouseout');
			$(id).unbind('mouseover').unbind('mouseout');

			$(this).mouseover(function(e)
			{
				clearTimeout(tooltipTimeout);
				var text = GetContent(this);

				if (text !== null)
				{
					if ($(id).length === 0)
					{
						html.prependTo(document.body);
					}

					$(id).html(text);
				}

				if (typeof settings.callback == 'function')
				{
					settings.callback.call(this);
				}

				if ($(id).find('a').length !== 0)
				{
					interact = true;
				}
				else
				{
					interact = false;
					$(id).html('<span>' + text + '</span>');
				}

				GetPosition(e, id, this);

				tooltipTimeout = setTimeout(function()
				{
					if (settings.fade)
					{
						$(id).fadeIn(settings.elementDelay);
					}
					else
					{
						$(id).show();
					}

				}, 100);

				$(id).mouseover(function(e)
				{
					if (interact)
					{
						clearTimeout(tooltipTimeout);
						$(id).stop();

						if (settings.fade)
						{
							$(id).animate({ 'opacity': '1' }, 150);
						}
						else
						{
							$(id).show();
						}
					}
				});
			});

			$(this).mousemove(function(e)
			{
				if (settings.track)
				{
					GetPosition(e, id, this);
				}
			});

			$(this).click(function()
			{
				clearTimeout(tooltipTimeout);

				tooltipTimeout = setTimeout(function()
				{
					if (settings.fade)
					{
						if (interact)
						{
							$(id).fadeOut(settings.elementDelay + 300);
						}
						else
						{
							$(id).fadeOut(settings.elementDelay);
						}
					}
					else
					{
						$(id).hide();
					}

				}, 100);

				$(id).mouseout(function()
				{
					if (interact)
					{
						clearTimeout(tooltipTimeout);

						tooltipTimeout = setTimeout(function()
						{
							if (settings.fade)
							{
								$(id).fadeOut(settings.elementDelay + 300);
							}
							else
							{
								$(id).hide();
							}

						}, 100);
					}
				});

				if (settings.attrFlag === 0)
				{
					$(this).attr('alt', settings.title);
				}
				else if (settings.attrFlag == 1)
				{
					$(this).attr('title', settings.title);
				}
			});

			$(this).mouseout(function()
			{
				clearTimeout(tooltipTimeout);

				tooltipTimeout = setTimeout(function()
				{
					if (settings.fade)
					{
						if (interact)
						{
							$(id).fadeOut(settings.elementDelay + 300);
						}
						else
						{
							$(id).fadeOut(settings.elementDelay);
						}
					}
					else
					{
						$(id).hide();
					}
				}, 100);

				$(id).mouseout(function()
				{
					if (interact)
					{
						clearTimeout(tooltipTimeout);

						tooltipTimeout = setTimeout(function()
						{
							if (settings.fade)
							{
								$(id).fadeOut(settings.elementDelay + 300);
							}
							else
							{
								$(id).hide();
							}

						}, 100);
					}
				});

				if (settings.attrFlag === 0)
				{
					$(this).attr('alt', settings.title);
				}
				else if (settings.attrFlag == 1)
				{
					$(this).attr('title', settings.title);
				}
			});
		});
	};
} (jQuery));